﻿using System;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using JPR.Common.Implementations;
using JPR.Common.Interfaces;
using JPR.TunelProxy.Interfaces;
using JPR.TunelProxy.Proxy.Implementations;
using Microsoft.Practices.Unity;

namespace JPR.TunelProxy.Proxy
{
    internal class Program
    {
        internal static UnityContainer Container;

        private static void Main(string[] args)
        {
            SetupContainer();
            try
            {
                IListener listener = Container.Resolve<SocketListener>();
                listener.ListenAndAcceptAsync();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Container.Resolve<ILogger>().WriteException(ex);
            }
            Console.In.ReadLine();
        }

        private static void SetupContainer()
        {
            Container = new UnityContainer();
            Container.RegisterType<ILogger, Logger>(new ContainerControlledLifetimeManager());
            Container.RegisterType<IListener, SocketListener>(new PerResolveLifetimeManager(),
                                                               new InjectionConstructor(),
                                                               new InjectionProperty("ConfigProvider"),
                                                               new InjectionProperty("Container", Container));
            Container.RegisterType<IClientDatagramProvider, SocketDatagramProvider>(new PerThreadLifetimeManager());
            Container.RegisterType<IServerDatagramProvider, SocketDatagramProvider>(new PerThreadLifetimeManager());
            Container.RegisterType<IConfigProvider, ConfigProvider>(new ContainerControlledLifetimeManager());
            Container.RegisterType<IFormatter, BinaryFormatter>(new PerThreadLifetimeManager());
            Container.RegisterType<IHttpHeadersFormatter, CloseConnectionHttpHeadersFormatter>(
                new ContainerControlledLifetimeManager());
            Container.RegisterType<IProxyWorker, ProxyWorker>(new PerThreadLifetimeManager(),
                                                               new InjectionProperty("ServerDatagramProvider"),
                                                               new InjectionProperty("Formatter"),
                                                               new InjectionProperty("ConfigProvider"),
                                                               new InjectionProperty("HttpParser"));
            Container.RegisterType<IHttpParser, HttpParser>(new TransientLifetimeManager());
        }
    }
}